<template>
    <div class="widget-form-container">
        <el-form
            :size="data.config.size"
            :label-position="data.config.labelPosition"
            :label-width="data.config.labelWidth + 'px'"
            :style="{position: 'relative',margin: '20px auto',width: data.config.width+'px',height: data.config.height+'px',background: data.config.background}"
        >
            <draggable
                class="widget-form-list"
                v-model="data.list"
                v-bind="{group:'people', ghostClass: 'ghost'}"
                @add="handleWidgetAdd"
            >
                <template v-for="(element, index) in data.list">
                    <VueDragResize
                        :is-active="activeRect==index"
                        :minw="50"
                        :minh="32"
                        :parentLimitation="true"
                        :w="Number(element.options.width)"
                        :h="Number(element.options.height)"
                        :x="Number(element.options.left)"
                        :y="Number(element.options.top)"
                        :z="data.list.length-index"
                        @clicked="onActivated(index)"
                        @resizing="resize($event,index)"
                        @dragging="resize($event,index)"
                        :key="element.key">
                        <widget-form-item @mobanClick="mobanClick" v-if="element && element.key" :key="element.key" :element="element" :select.sync="selectWidget" :index="index" :data="data"/>
                    </VueDragResize>
                </template>
            </draggable>
        </el-form>
    </div>
</template>
<style lang="scss" scoped>
    .widget-form-container .widget-form-list{
        padding: 0;
        box-shadow: 0 0 2px #aaa;
    }
</style>
<script>
import Draggable from 'vuedraggable'
import VueDragResize from 'vue-drag-resize'
import WidgetFormItem from './WidgetFormItem'
import deepClone from '@/utils/deepClone'
export default {
    components: {
        Draggable,
        WidgetFormItem,
        VueDragResize
    },
    props: ['data', 'select', 'activeRect'],
    data() {
        return {
            selectWidget: this.select
        }
    },
    watch: {
        select(val) {
            this.selectWidget = val
        },
        selectWidget: {
            handler(val) {
                this.$emit('update:select', val)
            },
            deep: true
        }
    },
    mounted() {
        document.body.ondrop = function(event) {
            const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
            if (isFirefox) {
                event.preventDefault()
                event.stopPropagation()
            }
        }
    },
    methods: {
        onActivated(index) {
            this.$emit('activeRect', index)
        },
        mobanClick(el){
            this.$emit('mobanClick',el);
        },
        resize(newRect, index) {
            const pW=this.data.config.width;
            const pH=this.data.config.height;
            this.data.list[index].options.width = newRect.width>pW ? pW : newRect.width
            this.data.list[index].options.height = newRect.height
            this.data.list[index].options.top = newRect.top
            this.data.list[index].options.left = newRect.left
        },
        handleSelectWidget(index) {
            this.selectWidget = this.data.list[index]
        },
        handleWidgetAdd(evt) {
            const newIndex = evt.newIndex
            const to = evt.to
            // 为拖拽到容器的元素添加唯一 key
            const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
            this.data.list = deepClone(this.data.list)
            this.$set(this.data.list, newIndex, {
                ...this.data.list[newIndex],
                options: {
                    ...this.data.list[newIndex].options,
                    remoteFunc: 'func_' + key
                },
                key,
                // 绑定键值
                model: this.data.list[newIndex].type + '_' + key,
                rules: []
            })

            if (this.data.list[newIndex].type === 'radio' || this.data.list[newIndex].type === 'checkbox' || this.data.list[newIndex].type === 'select') {
                this.$set(this.data.list, newIndex, {
                    ...this.data.list[newIndex],
                    options: {
                        ...this.data.list[newIndex].options,
                        options: this.data.list[newIndex].options.options.map(item => ({
                            ...item
                        }))
                    }
                })
            }

            if (this.data.list[newIndex].type === 'BaseGrid') {
                this.$set(this.data.list, newIndex, {
                    ...this.data.list[newIndex],
                    columns: this.data.list[newIndex].columns.map(item => ({ ...item }))
                })
            }

            this.selectWidget = this.data.list[newIndex]
        },
        handleWidgetColAdd($event, row, colIndex) {
            const newIndex = $event.newIndex
            const oldIndex = $event.oldIndex
            const item = $event.item

            // 防止布局元素的嵌套拖拽
            if (item.className.indexOf('data-grid') >= 0) {
                // 如果是列表中拖拽的元素需要还原到原来位置
                item.tagName === 'DIV' && this.data.list.splice(oldIndex, 0, row.columns[colIndex].list[newIndex])

                row.columns[colIndex].list.splice(newIndex, 1)

                return false
            }

            const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
            this.data.list = deepClone(this.data.list)
            this.$set(row.columns[colIndex].list, newIndex, {
                ...row.columns[colIndex].list[newIndex],
                options: {
                    ...row.columns[colIndex].list[newIndex].options,
                    remoteFunc: 'func_' + key
                },
                key,
                // 绑定键值
                model: row.columns[colIndex].list[newIndex].type + '_' + key,
                rules: []
            })

            if (row.columns[colIndex].list[newIndex].type === 'radio' || row.columns[colIndex].list[newIndex].type === 'checkbox' || this.data.list[newIndex].type === 'select') {
                this.$set(row.columns[colIndex].list, newIndex, {
                    ...row.columns[colIndex].list[newIndex],
                    options: {
                        ...row.columns[colIndex].list[newIndex].options,
                        options: row.columns[colIndex].list[newIndex].options.options.map(item => ({
                            ...item
                        }))
                    }
                })
            }

            this.selectWidget = row.columns[colIndex].list[newIndex]
        },
        handleWidgetDelete(index) {
            if (this.data.list.length - 1 === index) {
                if (index === 0) {
                    this.selectWidget = {}
                } else {
                    this.selectWidget = this.data.list[index - 1]
                }
            } else {
                this.selectWidget = this.data.list[index + 1]
            }

            this.$nextTick(() => {
                this.data.list.splice(index, 1)
            })
        }
    }
}
</script>
